#!/bin/sh
# This regression test is a part of SIPp.
# A pcap play reads each packet's own Ethernet header, with or without
# an 802.1Q tag, and steps over IPv6 extension headers: all four UDP
# packets of the capture are played.
. "`dirname "$0"`/../functions"

# Sending pcap plays needs a raw socket: run as root in a user and
# network namespace of our own.
if test -z "$SIPP_NETNS"; then
    if unshare -rn true 2>/dev/null; then
        SIPP_NETNS=1 exec unshare -rn "$0"
    fi
    init
    skip "no user network namespaces"
fi
init
"`get_sipp`" -v | grep -q PCAP || skip "no PCAP"
ip link set lo up 2>/dev/null || skip "cannot bring up lo"

# UDP over IPv4, IPv4 in an 802.1Q tag, and IPv6 behind a hop-by-hop
# and behind a destination options header, 20 ms apart, on Ethernet.
perl -e '
    sub rec {
        my ($f) = @_; $t += 20000;
        pack("VVVV", 1, $t, length($f), length($f)) . $f;
    }
    sub udp { pack("nnnn", 5000, 6000, 20, 0) . pack("CCn", 0x80, 0, $_[0])
        . "\0" x 8 }
    sub ip4 { pack("CCnnnCCn", 0x45, 0, 20 + length($_[0]), 0, 0, 64, 17, 0)
        . "\x7f\0\0\x01\x7f\0\0\x01" . $_[0] }
    sub ip6 { my ($nxt, $ext, $u) = @_;
        pack("NnCC", 0x60000000, length($ext) + length($u), $nxt, 64)
        . "\0" x 15 . "\x01" . "\0" x 15 . "\x01" . $ext . $u }
    $mac = "\x02\0\0\0\0\x01\x02\0\0\0\0\x02";
    $opt = pack("CC", 17, 0) . "\x01\x04\0\0\0\0";
    print pack("VvvlVVV", 0xa1b2c3d4, 2, 4, 0, 0, 65535, 1),
        rec($mac . "\x08\x00" . ip4(udp(1))),
        rec($mac . "\x81\x00\x00\x05\x08\x00" . ip4(udp(2))),
        rec($mac . "\x86\xdd" . ip6(0, $opt, udp(3))),
        rec($mac . "\x86\xdd" . ip6(60, $opt, udp(4)));
' >play.pcap
rm -f rtp.out
perl -e '
    use Socket;$|=1;(socket(S,PF_INET,SOCK_DGRAM,17)&&
    bind(S,pack_sockaddr_in(26630,inet_aton("127.0.0.1")))&&
    setsockopt(S,SOL_SOCKET,SO_RCVTIMEO,pack("L!L!",3,0)))||die($!);
    while (recv(S,$o,2048,0)) { print unpack("x2n", $o), " " }
    print "\n";' >rtp.out &
sippbg -sf uas.xml -i 127.0.0.1 -p 25634 -m 1 -timeout 8
sippfg -sf uac.xml -i 127.0.0.1 -p 25635 -m 1 -mp 26634 \
    127.0.0.1:25634 -timeout 8 -timeout_error >/dev/null 2>&1
status=$?
wait
read seqs <rtp.out
rm -f play.pcap rtp.out

if test $status -ne 0; then
    fail "UAC failed with $status"
elif test "$seqs" != "1 2 3 4"; then
    fail "played packets ${seqs:-none}, not 1 2 3 4"
else
    ok
fi
